package com.aiti.lulian.gxmh.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import com.aiti.base.core.constant.MessageCodeConstant;
import com.aiti.base.core.exception.BusinessException;
import com.aiti.base.core.utils.message.Message;
import com.aiti.framework.commons.dictmodel.entity.SysDictData;
import com.aiti.framework.commons.dictmodel.mapper.SysDictDataMapper;
import com.aiti.lulian.dto.OcrBusinessLicenseDto;
import com.aiti.lulian.dto.SearchDto;
import com.aiti.lulian.entity.*;
import com.aiti.lulian.feign.CloudShowManagerSubService;
import com.aiti.lulian.feign.ScaleEnterpriseService;
import com.aiti.lulian.gxmh.dto.GxmhUserRegisterDto;
import com.aiti.lulian.gxmh.dto.SysUserDto;
import com.aiti.lulian.gxmh.dto.UserEnterpriseParamDto;
import com.aiti.lulian.mapper.*;
import com.aiti.lulian.mapper.gxmh.GxmhSysMapper;
import com.aiti.lulian.ocr.BusinessLicenseResult;
import com.aiti.lulian.ocr.OcrService;
import com.aiti.lulian.service.ILuLianEnterpriseMainIndustrySerivce;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * description: 工信门户，用户和企业认证
 * auth fcb
 * date 2025-06-19 15:52
 **/
@Service
@Slf4j
public class GxmhUserService {

    @Autowired
    private GxmhSysMapper gxmhSysMapper;
    @Autowired
    private LuLianEnterpriseUserMapper luLianEnterpriseUserMapper;
    @Autowired
    private LuLianEnterpriseHistoryMapper luLianEnterpriseHistoryMapper;
    @Autowired
    private ILuLianEnterpriseMainIndustrySerivce luLianEnterpriseMainIndustrySerivce;
    @Autowired
    private CloudShowManagerSubService cloudShowManagerSubService;

    @Autowired
    private LuLianEnterpriseMapper luLianEnterpriseMapper;
    @Autowired
    private LuLianEnterpriseProveMapper luLianEnterpriseProveMapper;
    @Autowired
    private SysAreaMapper sysAreaMapper;
    @Autowired
    private SysDictDataMapper sysDictDataMapper;
    @Autowired
    private ScaleEnterpriseService scaleEnterpriseService;
    @Autowired
    private GxmhXLBService gxmhXLBService;
    @Autowired
    private OcrService ocrService;

    /**
     * 判断该用户是否已经存在
     * 存在：true
     * @param username
     * @return
     */
    public Boolean queryUserRegisterCount(String username) {
        return gxmhSysMapper.queryUserRegisterCount(username) > 0;
    }


    /**
     * 判断用户是否绑定了企业
     * true:已绑定
     * @param username
     * @param userId
     * @return
     */
    public Boolean queryUserEnterpriseCount(String username, String userId) {
        if(StrUtil.isEmpty(username) && StrUtil.isEmpty(userId)) {
            throw new BusinessException("用户名和用户ID不能同时为空");
        }
        if(StrUtil.isEmpty(userId)) {
            String id = gxmhSysMapper.queryUserIdByUsername(username);
            if(StrUtil.isEmpty(id)) {
                throw new BusinessException("用户不存在");
            }
            String enterpriseId = gxmhSysMapper.queryEnterpriseIdByUserId(id);
            return StrUtil.isNotEmpty(enterpriseId);
        }
        String enterpriseId = gxmhSysMapper.queryEnterpriseIdByUserId(userId);
        return StrUtil.isNotEmpty(enterpriseId);
    }

    /**
     * 完善个人信息.
     * 当前登录小程序的用户没有企业id的时候需要完善个人信息
     * @param dto
     */
    @Transactional(rollbackFor = Throwable.class)
    public void insertUserRegisterInfo(GxmhUserRegisterDto dto) {
        this.checkParam(dto);
        String userId = gxmhSysMapper.queryUserIdByUsername(dto.getUsername());
        if(StrUtil.isEmpty(userId)) {
            throw new BusinessException("用户不存在");
        }
        // 更新用户信息
        gxmhSysMapper.updateUserInfo(dto, userId);
        // 处理企业名称
        String extentInfoBaseId = gxmhSysMapper.queryUserExtentInfoBaseId(userId);
        if(StrUtil.isEmpty(extentInfoBaseId)) {
            // 插入企业名称
            gxmhSysMapper.insertUserExtentInfo(IdUtil.simpleUUID(), userId, dto.getGxmhEnterpriseName());
        }
        // 如果当前用户没有任何角色则创建个人的角色
        List<String> userRoleList = gxmhSysMapper.queryUserRoleList(userId);
        if(CollectionUtil.isEmpty(userRoleList)) {
            gxmhSysMapper.insertUserRole(IdUtil.simpleUUID(), userId,"c297ac5995d941d2b0b05c2048747713");
        }
    }

    /**
     * 注册企业信息
     * @param dto
     */
    @Transactional(rollbackFor = Throwable.class)
    public void registerEnterpriseInfo(UserEnterpriseParamDto dto) {
        this.checkUserEnterpriseParam(dto);
        // 1. 查询用户是否已关联企业
        Integer enterpriseUserCount = luLianEnterpriseUserMapper.selectEnterpriseCountByUserId(dto.getUserId());
        if(enterpriseUserCount > 0) {
            throw new BusinessException("该用户已经关联企业，请勿重复关联");
        }
        // 2. 查询企业是否已经存在
        List<String> nameList = luLianEnterpriseHistoryMapper.getEnterpriseIdByName(dto.getEnterpriseName());
        if(CollectionUtil.isNotEmpty(nameList) && nameList.size() > 1) {
            throw new BusinessException("存在多个【"+dto.getEnterpriseName()+"】企业，无法绑定用户");
        }
        if(CollectionUtil.isNotEmpty(nameList) && nameList.size() == 1) {
            // 3. 企业存在，查询该企业是否绑定了用户。如果绑定了多个，先只返回一个
            String enterpriseId = nameList.get(0);
            String bindedUserId = gxmhSysMapper.queryBindedUserIdByEnterpriseId(enterpriseId);
            if(StrUtil.isNotEmpty(bindedUserId)) {
                // 返回提示信息
                SysUserDto sysUserDto = gxmhSysMapper.queryUserInfo(bindedUserId);
                if(sysUserDto == null) {
                    throw new BusinessException("用户不存在");
                }
                if(StrUtil.isBlank(sysUserDto.getRealname())) {
                    sysUserDto.setRealname("");
                }
                if(StrUtil.isBlank(sysUserDto.getMobile())) {
                    sysUserDto.setMobile("");
                }
                throw new BusinessException("您提交的企业信息已被其他账号认证(" + sysUserDto.getRealname()+sysUserDto.getMobile() + ")");
            }else {
                // 创建企业和用户的绑定关系
                LuLianEnterpriseUser enterpriseUser = LuLianEnterpriseUser.builder().enterpriseId(enterpriseId).baseId(IdUtil.simpleUUID()).userId(dto.getUserId()).build();
                luLianEnterpriseUserMapper.insert(enterpriseUser);
            }
            return;
        }
        // 4. 企业信息不存在，创建企业、企业和用户的绑定关系x
        String enterpriseId = IdUtil.simpleUUID();
        LuLianEnterpriseHistory enterpriseHistory = this.buildEnterpriseHistory(dto, enterpriseId);
        //验证营业执照信息以及获取小蓝本关于企业的信息
        validateBusinessLicense(enterpriseHistory, dto);
        fillByXlb(dto, enterpriseHistory);

        luLianEnterpriseHistoryMapper.insert(enterpriseHistory);
        //4.1创建上线企业
        LuLianEnterprise luLianEnterprise = new LuLianEnterprise();
        BeanUtil.copyProperties(enterpriseHistory,luLianEnterprise);
        luLianEnterpriseMapper.insert(luLianEnterprise);
        //保存营业执照
        LuLianEnterpriseProve luLianEnterpriseProve = LuLianEnterpriseProve.builder().baseId(IdUtil.simpleUUID()).enterpriseId(enterpriseId).businessLicenseUrl(dto.getBusinessLicenseUrl()).build();
        luLianEnterpriseProveMapper.insert(luLianEnterpriseProve);
        //保存数据到Search表中
        SearchDto searchDto = getSearchDto(dto, enterpriseHistory);
        Message scaleMessage = scaleEnterpriseService.addEnterprise(searchDto);
        if(scaleMessage.getCode() == 1){
            throw new RuntimeException("写入搜索库失败");
        }

        // 5. 创建企业和用户的绑定关系
        LuLianEnterpriseUser enterpriseUser = LuLianEnterpriseUser.builder().enterpriseId(enterpriseId).baseId(IdUtil.simpleUUID()).userId(dto.getUserId()).build();
        luLianEnterpriseUserMapper.insert(enterpriseUser);
        // 6. 保存行业
        LuLianEnterpriseMainIndustry mainIndustry = new LuLianEnterpriseMainIndustry();
        mainIndustry.setBaseId(IdUtil.simpleUUID());
        mainIndustry.setEnterpriseId(enterpriseId);
        mainIndustry.setFristDictId(dto.getFristDictId());
        mainIndustry.setSecondDictId(dto.getSecondDictId());
        luLianEnterpriseMainIndustrySerivce.save(mainIndustry);

        // 添加管理员角色，如果有个人角色，则将个人角色替换为企业管理员角色
        Map<String, String> params = new HashMap<>(16);
        params.put("userId", dto.getUserId());
        params.put("roleId", "043ea2e3e02c4aa591df1f83e65069bc");
        Message me = cloudShowManagerSubService.addUserRoleNew(params);
        if(me.getCode().equals(MessageCodeConstant.MSG_FAIL_CODE)){
            throw new RuntimeException("保存用户角色失败");
        }
    }

    private void fillByXlb(UserEnterpriseParamDto dto, LuLianEnterpriseHistory enterpriseHistory) {
        Message message = gxmhXLBService.requestEnterpriseInfoByUscc(dto.getUnicode());
        if(MessageCodeConstant.MSG_SUCCESS_CODE.equals(message.getCode())){
            Map objMap = (Map) message.getObj();
            Map searchMap = (Map) objMap.get("search");
            Optional.ofNullable(searchMap).ifPresent(search -> {
                String eid = (String) searchMap.get("queryCompanyUscc");
                log.info("小蓝本查询出来的eid: " + eid);
                Message detailMessage = gxmhXLBService.requestEnterpriseInfoByEid(eid, null);
                if(MessageCodeConstant.MSG_SUCCESS_CODE.equals(detailMessage.getCode())){
                    Map obj = (Map)detailMessage.getObj();
                    Map entInfo = (Map)obj.get("entInfo");
                    Optional.ofNullable(entInfo).ifPresent(entInfoMap -> {
                        Map base = (Map)entInfoMap.get("base");
                        Optional.ofNullable(base).ifPresent(baseInfo -> {
                            log.info("小蓝本根据eid查询出来的企业信息: " + base);
                            Double registerCapital = (Double)baseInfo.get("register_capital");
                            enterpriseHistory.setRegisterCapital(registerCapital);
                            enterpriseHistory.setBaseNameEn((String)baseInfo.get("entNameEn"));
                            if(StrUtil.isEmpty(enterpriseHistory.getLegalPerson())){
                                enterpriseHistory.setLegalPerson((String)baseInfo.get("frname"));
                            }
                            if(enterpriseHistory.getRegisterTime()== null){
                                enterpriseHistory.setRegisterTime(DateUtil.parse((String)baseInfo.get("esdate"), "yyyy-MM-dd"));
                            }
                            enterpriseHistory.setAddress((String)baseInfo.get("addr"));
                            enterpriseHistory.setLongitude(String.valueOf(baseInfo.get("addrLng")));
                            enterpriseHistory.setLatitude(String.valueOf(baseInfo.get("addrLat")));
                            enterpriseHistory.setBaseIntroduction(String.valueOf(baseInfo.get("description")));
                            if(StrUtil.isEmpty(enterpriseHistory.getBusinessScope())){
                                enterpriseHistory.setBusinessScope(String.valueOf(baseInfo.get("opscope")));
                                enterpriseHistory.setBusinessNature(String.valueOf(baseInfo.get("opscope")));
                            }

                        });
                    });

                }
            });

        }
    }

    private void validateBusinessLicense(LuLianEnterpriseHistory enterpriseHistory, UserEnterpriseParamDto dto) {
        OcrBusinessLicenseDto ocrDto = new OcrBusinessLicenseDto();
        ocrDto.setUnicode(dto.getUnicode());
        ocrDto.setFileUrl(dto.getFileUrl());
        BusinessLicenseResult result = ocrService.exeOcrBusinessLicenseService(ocrDto);
        if(result.getData() == null) {
            throw new BusinessException("无法识别营业执照信息");
        }
        String creditCode = result.getData().getCreditCode();
        String companyName = result.getData().getCompanyName();
        if(!dto.getUnicode().equals(creditCode) || !dto.getEnterpriseName().equals(companyName)) {
            throw new BusinessException("营业执照信息与注册信息不一致");
        }
        enterpriseHistory.setIsAuth(true);
        enterpriseHistory.setStatus("1");
        enterpriseHistory.setExamineStatus("1");
        enterpriseHistory.setLegalPerson(result.getData().getLegalPerson());
        enterpriseHistory.setLegalPerson(result.getData().getLegalPerson());
        enterpriseHistory.setAddress(result.getData().getBusinessAddress());
        enterpriseHistory.setBusinessScope(result.getData().getBusinessScope());
        enterpriseHistory.setBusinessNature(result.getData().getBusinessScope());
        String fromDate = result.getData().getValidFromDate();
        if(StrUtil.isNotBlank(fromDate)){
            try{
                enterpriseHistory.setRegisterTime(DateUtil.parse(result.getData().getValidFromDate(), "yyyyMMdd"));
            }catch (Exception e) {

            }
        }
        String companyType = result.getData().getCompanyType();
        if(StrUtil.isNotBlank(companyType)){
            List<SysDictData> dictDateList = sysDictDataMapper.selectList(new LambdaQueryWrapper<SysDictData>().eq(SysDictData::getBaseName, companyType));
            if(!CollectionUtil.isEmpty(dictDateList)){
                enterpriseHistory.setRegisterType(dictDateList.get(0).getBaseId());
            }

        }


    }

    private SearchDto getSearchDto(UserEnterpriseParamDto dto, LuLianEnterpriseHistory enterpriseHistory) {
        //查询行政区
        SysArea sysArea = null;
        if(StringUtils.isNotBlank(enterpriseHistory.getCity())){
            sysArea = sysAreaMapper.selectById(enterpriseHistory.getCity());
        }
        SysDictData sysDictData = sysDictDataMapper.selectById(dto.getFristDictId());
        Double registerCapital = enterpriseHistory.getRegisterCapital() == null ? 0.0 : enterpriseHistory.getRegisterCapital();
        SearchDto searchDto = SearchDto.builder()
                .baseName(enterpriseHistory.getBaseName())
                .unicode(enterpriseHistory.getUnicode())
                .registerTime(enterpriseHistory.getRegisterTime() != null ? DateUtil.format(enterpriseHistory.getRegisterTime(), "yyyy/MM/dd") : null)
                .address(enterpriseHistory.getAddress())
                .businessScope(enterpriseHistory.getBusinessScope())
                .baseIntroduction(enterpriseHistory.getBaseIntroduction())
                .logo(enterpriseHistory.getLogo())
                .isLead(enterpriseHistory.getIsLead())
                .isGazelle(enterpriseHistory.getIsGazelle())
                .isChampion(enterpriseHistory.getIsChampion())
                .isSpecial(enterpriseHistory.getIsSpecial())
                .isGiant(enterpriseHistory.getIsGiant())
                .isUnicorn(enterpriseHistory.getIsUnicorn())
                .isHightech(enterpriseHistory.getIsHightech())
                .registerCapital(registerCapital == 0.0 ? null : String.valueOf(registerCapital))
                .build();
        if(sysArea != null && StringUtils.isNotBlank(sysArea.getBaseName())){
            searchDto.setCity(sysArea.getBaseName());
        }
        if(sysDictData != null && StringUtils.isNotBlank(sysDictData.getBaseName())){
            searchDto.setIndustry(sysDictData.getBaseName());
        }
        return searchDto;
    }

    private LuLianEnterpriseHistory buildEnterpriseHistory (UserEnterpriseParamDto dto, String enterpriseId){
        LuLianEnterpriseHistory enterpriseHistory = new LuLianEnterpriseHistory();
        enterpriseHistory.setBaseId(enterpriseId);
        enterpriseHistory.setBaseName(dto.getEnterpriseName());
        enterpriseHistory.setLinkMan(dto.getLinkMan());
        enterpriseHistory.setLinkPhone(dto.getLinkPhone());
        enterpriseHistory.setProvince(dto.getProvince());
        enterpriseHistory.setCity(dto.getCity());
        enterpriseHistory.setCounty(dto.getCounty());
        enterpriseHistory.setUnicode(dto.getUnicode());
        enterpriseHistory.setIsAuth(false);
        enterpriseHistory.setExamineStatus("");
        enterpriseHistory.setStatus("1");
        enterpriseHistory.setCreator(dto.getUserId());
        enterpriseHistory.setBaseCreateTime(DateUtil.formatDateTime(new Date()));

        return enterpriseHistory;
    }

    private void checkUserEnterpriseParam(UserEnterpriseParamDto dto) {
        if(StrUtil.isBlank(dto.getUserId())) {
            throw new BusinessException("用户ID不能为空");
        }
        if(StrUtil.isBlank(dto.getEnterpriseName())) {
            throw new BusinessException("企业名称不能为空");
        }
        if(StrUtil.isBlank(dto.getFristDictId())) {
            throw new BusinessException("所属行业不能为空");
        }
//        if(StrUtil.isEmpty(dto.getSecondDictId())) {
//            throw new BusinessException("所属行业不能为空");
//        }
        if(StrUtil.isBlank(dto.getProvince())) {
            throw new BusinessException("所在地区不能为空");
        }
        if(StrUtil.isBlank(dto.getCity())) {
            throw new BusinessException("所在地区不能为空");
        }
        if(StrUtil.isBlank(dto.getCounty())) {
            throw new BusinessException("所在地区不能为空");
        }
        if(StrUtil.isBlank(dto.getLinkMan())) {
            throw new BusinessException("联系人不能为空");
        }
        if(StrUtil.isBlank(dto.getLinkPhone())) {
            throw new BusinessException("联系电话不能为空");
        }
    }

    private void checkParam(GxmhUserRegisterDto dto) {
        if(StrUtil.isBlank(dto.getUsername())) {
            throw new BusinessException("用户注册手机号不能为空");
        }
        if(StrUtil.isBlank(dto.getRealname())) {
            throw new BusinessException("用户真实姓名不能为空");
        }
        if(StrUtil.isBlank(dto.getGxmhEnterpriseName())) {
            throw new BusinessException("用户注册企业名称不能为空");
        }
        if(StrUtil.isBlank(dto.getPosition())) {
            throw new BusinessException("用户职务不能为空");
        }
    }


}
